home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
x2ftp
/
msdos
/
mxcode
/
fmplay11
/
rol2scr.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-07-26
|
7KB
|
264 lines
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include"adlib.h"
/* Noooo. Don't look at this code, turn back before it's too late! */
void FMLoadInstrument(char *insName,char *bankFile,FMInstrument *ins);
char insTable[255][9]; /* arrays are the best data structure conceivable */
/* This is the .scr file format. Good luck.
char percussive mode
char nm instruments
instrument data, 28 bytes per.
0, char voice, char pitch, unsigned duration ; play note
; duration is in ticks, and pitch is one of those 11-123 numbers
1, char voice, char new volume
2, char voice, char new voice data
3, int # ticks to pause
4, end of song
*/
#define NMVOICES 11
void flushWait(int waitTime,FILE *ofile)
{BYTE b;
int i;
if (!waitTime)
return;
b=3;
fwrite(&b,sizeof(BYTE),1,ofile);
i=waitTime;
fwrite(&i,sizeof(i),1,ofile);
}
void translateROL(char *rolName,char *outputName,char *bankFile)
{FILE *rfile,*ofile;
BYTE b,perc;
long rolSize;
int j,i,v,tick,done,wait;
BYTE nmInstruments;
BYTE *rol,*tempoEvent,*noteEvent[NMVOICES],*p,
*insEvent[NMVOICES],*volumeEvent[NMVOICES],*pitchEvent[NMVOICES];
int nmTempo,nmTicks[NMVOICES],nmIns[NMVOICES],nmVolume[NMVOICES],
ticksLeft[NMVOICES],nmPitch[NMVOICES];
rfile=fopen(rolName,"rb");
if (!rfile)
{printf("Can't open .rol file.\n");
exit(-1);
}
fseek(rfile,0,SEEK_END);
rolSize=ftell(rfile);
fseek(rfile,0,SEEK_SET);
rol=(BYTE *)malloc(sizeof(BYTE)*rolSize);
if (!rol)
{printf("Not enough memory. (or .rol file too big)\n");
exit(-1);
}
if (fread(rol,sizeof(BYTE),rolSize,rfile)!=rolSize)
{printf("Error reading .rol\n");
exit(-1);
}
fclose(rfile);
ofile=fopen(outputName,"wb");
if (!ofile)
{printf("Can't open output file.\n");
exit(-1);
}
b=rol[53];
if (b)
b=0;
else
b=1;
fwrite(&b,sizeof(b),1,ofile); /* read and write percussive flag */
perc=b;
/* seek to tempo events */
p=&(rol[201]);
nmTempo=*((int *)p);
tempoEvent=p+2;
p+=2+nmTempo*6;
for (v=0;v<NMVOICES;v++)
{p+=15;
nmTicks[v]=*((int *)p);
i=0;
p+=2;
noteEvent[v]=p;
while (i<nmTicks[v])
{i+=*((int *)(p+2));
p+=4;
}
p+=15;
nmIns[v]=*((int *)p);
p+=2;
insEvent[v]=p;
p+=nmIns[v]*14;
p+=15;
nmVolume[v]=*((int *)p);
p+=2;
volumeEvent[v]=p;
p+=nmVolume[v]*6;
p+=15;
nmPitch[v]=*((int *)p);
p+=2;
pitchEvent[v]=p;
p+=nmPitch[v]*6;
}
for (i=0;i<255;i++)
strcpy(insTable[i],"");
nmInstruments=0;
for (v=0;v<NMVOICES;v++)
{for (i=0;i<nmIns[v];i++)
{char *insName;
insName=(char *)(insEvent[v]+2+i*14);
for (j=0;j<nmInstruments;j++)
{if (!stricmp(insName,insTable[j]))
break;
}
if (j==nmInstruments)
strcpy(insTable[nmInstruments++],insName);
}
}
fwrite(&nmInstruments,sizeof(nmInstruments),1,ofile);
{FMInstrument ins;
for (i=0;i<nmInstruments;i++)
{FMLoadInstrument(insTable[i],bankFile,&ins);
fwrite(&ins,sizeof(ins),1,ofile);
}
}
tick=0;
for (i=0;i<NMVOICES;i++)
ticksLeft[i]=0;
done=0;
wait=0;
while (!done)
{done=1;
for (i=0;i<(perc?NMVOICES:9);i++)
{/* for every voice */
if (nmIns[i]>0)
{if (*((int *)(insEvent[i]))==tick)
{char *name;
flushWait(wait,ofile);
wait=0;
name=insEvent[i]+2;
for (j=0;j<nmInstruments;j++)
{if (!stricmp(name,insTable[j]))
break;
}
if (j==nmInstruments)
{printf("Arrggghh!\n");
exit(-1);
}
b=2;
fwrite(&b,sizeof(BYTE),1,ofile);
b=i;
fwrite(&b,sizeof(BYTE),1,ofile);
b=j;
fwrite(&b,sizeof(BYTE),1,ofile);
nmIns[i]--;
insEvent[i]+=14;
}
}
if (tick<nmTicks[i])
{done=0;
if (--ticksLeft[i]<=0)
{int num,duration;
num=*((int *)(noteEvent[i]));
duration=*((int *)(noteEvent[i]+2));
noteEvent[i]+=4;
ticksLeft[i]=duration;
if (num!=0)
{BYTE b;
flushWait(wait,ofile);
wait=0;
b=0;
fwrite(&b,sizeof(BYTE),1,ofile);
b=i;
fwrite(&b,sizeof(BYTE),1,ofile);
b=num;
fwrite(&b,sizeof(BYTE),1,ofile);
fwrite(&duration,sizeof(duration),1,ofile);
}
}
}
}
wait++;
tick++;
}
b=4;
fwrite(&b,sizeof(BYTE),1,ofile);
free(rol);
fclose(ofile);
}
/* the compiler better not decide to rearrange these structures!!! */
struct nameRecord
{unsigned short index;
char used;
char name[9];
};
#define GET(x) fread(&(ins->x),sizeof(ins->x),1,bFile)
void FMLoadInstrument(char *insName,char *bankFile,FMInstrument *ins)
{FILE *bFile;
short int nmRecords,crap;
long int nameStart,dataStart;
struct nameRecord nr;
int i;
printf("Searching for %s...\n",insName);
bFile=fopen(bankFile,"rb");
if (!bFile)
{printf("Can't find bank file.\n");
exit(-1);
}
if (fseek(bFile,8,SEEK_SET))
{printf("Error reading bank file.\n");
exit(-1);
}
fread(&nmRecords,sizeof(nmRecords),1,bFile);
fread(&crap,sizeof(crap),1,bFile);
fread(&nameStart,sizeof(nameStart),1,bFile);
fread(&dataStart,sizeof(dataStart),1,bFile);
for (i=0;i<nmRecords;i++)
{fseek(bFile,nameStart+12*i,SEEK_SET);
fread(&nr,sizeof(nr),1,bFile);
if (nr.used && !stricmp(nr.name,insName))
break;
}
if (i==nmRecords)
{printf("Instrument: %s not found in bank file.\n",insName);
exit(-1);
}
fseek(bFile,dataStart+nr.index*30,SEEK_SET);
GET(MOD_waveForm); GET(MOD_waveForm);
GET(MOD_KSL); GET(MOD_fMult); GET(feedBack); GET(MOD_attack);
GET(MOD_sustain); GET(MOD_ss); GET(MOD_decay); GET(MOD_release);
GET(MOD_outputLevel); GET(MOD_amplitudeVibrato); GET(MOD_frequencyVibrato);
GET(MOD_envelopeScaling); GET(FM);
GET(CAR_KSL); GET(CAR_fMult); GET(MOD_waveForm); GET(CAR_attack);
GET(CAR_sustain); GET(CAR_ss); GET(CAR_decay); GET(CAR_release);
GET(CAR_outputLevel); GET(CAR_amplitudeVibrato); GET(CAR_frequencyVibrato);
GET(CAR_envelopeScaling); GET(MOD_waveForm);
GET(MOD_waveForm); GET(CAR_waveForm);
fclose(bFile);
}
int main(int argc,char **argv)
{if (argc!=4)
{printf("Look, here's how it goes:\n");
printf(" %s <input file> <output_file> <bank_file>\n",argv[0]);
exit(-1);
}
translateROL(argv[1],argv[2],argv[3]);
printf("Okey dokey.\n");
return 0;
}